using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Caching.Distributed;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Timing;
using Matrix.Notification.Application.Channels;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Security.Cryptography;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;

namespace Matrix.Notification.Services
{
    /// <summary>
    /// 默认推送通知服务实现
    /// </summary>
    public class DefaultPushNotificationService : IPushNotificationService, ITransientDependency
    {
        private readonly ILogger<DefaultPushNotificationService> _logger;
        private readonly IClock _clock;
        private readonly IDistributedCache _cache;
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly PushNotificationOptions _options;

        public DefaultPushNotificationService(
            ILogger<DefaultPushNotificationService> logger,
            IClock clock,
            IDistributedCache cache,
            IHttpClientFactory httpClientFactory,
            IOptions<PushNotificationOptions> options)
        {
            _logger = logger;
            _clock = clock;
            _cache = cache;
            _httpClientFactory = httpClientFactory;
            _options = options.Value;
        }

        public async Task<PushNotificationResult> SendAsync(
            PushNotificationMessage message,
            string deviceToken,
            PushPlatform platform,
            CancellationToken cancellationToken = default)
        {
            var result = new PushNotificationResult
            {
                DeviceToken = deviceToken,
                Platform = platform,
                SentTime = _clock.Now
            };

            try
            {
                _logger.LogInformation("开始发送推送通知: Platform={Platform}, DeviceToken={DeviceToken}, Title={Title}",
                    platform, MaskDeviceToken(deviceToken), message.Title);

                switch (platform)
                {
                    case PushPlatform.FCM:
                        result = await SendFCMNotificationAsync(message, deviceToken, cancellationToken);
                        break;
                    case PushPlatform.APNS:
                        result = await SendAPNSNotificationAsync(message, deviceToken, cancellationToken);
                        break;
                    case PushPlatform.HMS:
                        result = await SendHMSNotificationAsync(message, deviceToken, cancellationToken);
                        break;
                    default:
                        result.Success = false;
                        result.ErrorMessage = $"不支持的推送平台: {platform}";
                        break;
                }

                if (result.Success)
                {
                    _logger.LogInformation("推送通知发送成功: MessageId={MessageId}, Platform={Platform}, DeviceToken={DeviceToken}",
                        result.MessageId, platform, MaskDeviceToken(deviceToken));
                }
                else
                {
                    _logger.LogWarning("推送通知发送失败: Platform={Platform}, DeviceToken={DeviceToken}, Error={Error}",
                        platform, MaskDeviceToken(deviceToken), result.ErrorMessage);
                }

                // 更新统计信息
                await UpdateStatisticsAsync(platform, result.Success, result.ErrorMessage);

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "推送通知发送异常: Platform={Platform}, DeviceToken={DeviceToken}",
                    platform, MaskDeviceToken(deviceToken));

                result.Success = false;
                result.ErrorMessage = ex.Message;
                result.ErrorCode = "EXCEPTION";

                await UpdateStatisticsAsync(platform, false, ex.Message);
                return result;
            }
        }

        public async Task<List<PushNotificationResult>> SendBatchAsync(
            PushNotificationMessage message,
            IEnumerable<string> deviceTokens,
            PushPlatform platform,
            CancellationToken cancellationToken = default)
        {
            var results = new List<PushNotificationResult>();
            var tokenList = deviceTokens.ToList();

            _logger.LogInformation("开始批量发送推送通知: Platform={Platform}, Count={Count}",
                platform, tokenList.Count);

            if (platform == PushPlatform.FCM && tokenList.Count > 0)
            {
                // FCM 支持批量推送
                var batchResults = await SendFCMBatchNotificationAsync(message, tokenList, cancellationToken);
                results.AddRange(batchResults);
            }
            else
            {
                // 其他平台使用并发单个发送
                var tasks = tokenList.Select(async token =>
                {
                    var result = await SendAsync(message, token, platform, cancellationToken);
                    return result;
                });

                var batchResultList = await Task.WhenAll(tasks);
                results.AddRange(batchResultList);
            }

            var successCount = results.Count(r => r.Success);
            var failureCount = results.Count(r => !r.Success);

            _logger.LogInformation(
                "批量推送通知完成: Platform={Platform}, Total={Total}, Success={Success}, Failed={Failed}",
                platform, results.Count, successCount, failureCount);

            return results;
        }

        public async Task<bool> ValidateDeviceTokenAsync(
            string deviceToken,
            PushPlatform platform,
            CancellationToken cancellationToken = default)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(deviceToken))
                {
                    return false;
                }

                return platform switch
                {
                    PushPlatform.FCM => ValidateFCMToken(deviceToken),
                    PushPlatform.APNS => ValidateAPNSToken(deviceToken),
                    PushPlatform.HMS => ValidateHMSToken(deviceToken),
                    _ => false
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "设备令牌验证失败: Platform={Platform}, DeviceToken={DeviceToken}",
                    platform, MaskDeviceToken(deviceToken));
                return false;
            }
        }

        public async Task<PushPlatform?> DetectPlatformAsync(
            string deviceToken,
            CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrWhiteSpace(deviceToken))
            {
                return null;
            }

            // 基于令牌格式检测平台
            if (ValidateFCMToken(deviceToken))
            {
                return PushPlatform.FCM;
            }

            if (ValidateAPNSToken(deviceToken))
            {
                return PushPlatform.APNS;
            }

            if (ValidateHMSToken(deviceToken))
            {
                return PushPlatform.HMS;
            }

            return null;
        }

        public async Task<PushNotificationStatistics> GetStatisticsAsync(
            PushPlatform? platform = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            CancellationToken cancellationToken = default)
        {
            var cacheKey = $"push_statistics:{platform?.ToString() ?? "all"}:{startTime?.Date:yyyy-MM-dd}";
            var cachedStats = await _cache.GetStringAsync(cacheKey, cancellationToken);

            if (!string.IsNullOrEmpty(cachedStats))
            {
                return JsonSerializer.Deserialize<PushNotificationStatistics>(cachedStats)!;
            }

            // 生成模拟统计数据，实际项目中应从数据库获取
            var statistics = new PushNotificationStatistics
            {
                Platform = platform,
                StartTime = startTime ?? _clock.Now.AddDays(-7),
                EndTime = endTime ?? _clock.Now,
                TotalSent = new Random().Next(1000, 10000),
                SuccessCount = new Random().Next(800, 9000),
                AveragePushTimeMs = new Random().Next(100, 1000)
            };

            statistics.FailureCount = statistics.TotalSent - statistics.SuccessCount;

            // 缓存统计结果
            await _cache.SetStringAsync(
                cacheKey,
                JsonSerializer.Serialize(statistics),
                new DistributedCacheEntryOptions
                {
                    AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5)
                },
                cancellationToken);

            return statistics;
        }

        public async Task<bool> IsAvailableAsync(
            PushPlatform platform,
            CancellationToken cancellationToken = default)
        {
            try
            {
                return platform switch
                {
                    PushPlatform.FCM => !string.IsNullOrEmpty(_options.FCM?.ServerKey),
                    PushPlatform.APNS => !string.IsNullOrEmpty(_options.APNS?.PrivateKey) && !string.IsNullOrEmpty(_options.APNS?.TeamId),
                    PushPlatform.HMS => !string.IsNullOrEmpty(_options.HMS?.AppId) && !string.IsNullOrEmpty(_options.HMS?.AppSecret),
                    _ => false
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查推送服务可用性失败: Platform={Platform}", platform);
                return false;
            }
        }

        #region FCM 实现

        private async Task<PushNotificationResult> SendFCMNotificationAsync(
            PushNotificationMessage message,
            string deviceToken,
            CancellationToken cancellationToken)
        {
            if (_options.FCM == null || string.IsNullOrEmpty(_options.FCM.ServerKey))
            {
                return new PushNotificationResult
                {
                    Success = false,
                    ErrorMessage = "FCM配置不完整",
                    ErrorCode = "CONFIG_MISSING"
                };
            }

            var httpClient = _httpClientFactory.CreateClient("FCM");
            var payload = new
            {
                message = new
                {
                    token = deviceToken,
                    notification = new
                    {
                        title = message.Title,
                        body = message.Body,
                        icon = message.Icon,
                        click_action = message.ClickUrl
                    },
                    data = message.Data ?? new Dictionary<string, object>(),
                    android = message.Android,
                    apns = message.Apns,
                    webpush = message.WebPush
                }
            };

            var json = JsonSerializer.Serialize(payload);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            httpClient.DefaultRequestHeaders.Authorization =
                new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _options.FCM.ServerKey);

            var response = await httpClient.PostAsync(
                "https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send",
                content,
                cancellationToken);

            var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
            var result = new PushNotificationResult
            {
                DeviceToken = deviceToken,
                Platform = PushPlatform.FCM,
                SentTime = _clock.Now
            };

            if (response.IsSuccessStatusCode)
            {
                result.Success = true;
                var responseData = JsonSerializer.Deserialize<JsonElement>(responseContent);
                if (responseData.TryGetProperty("name", out var nameProperty))
                {
                    result.MessageId = nameProperty.GetString();
                }
            }
            else
            {
                result.Success = false;
                result.ErrorMessage = $"FCM请求失败: {response.StatusCode}";
                result.ErrorCode = ((int)response.StatusCode).ToString();

                try
                {
                    var errorData = JsonSerializer.Deserialize<JsonElement>(responseContent);
                    if (errorData.TryGetProperty("error", out var errorProperty))
                    {
                        result.ErrorMessage = errorProperty.GetString();
                    }
                }
                catch
                {
                    // 忽略JSON解析错误
                }
            }

            return result;
        }

        private async Task<List<PushNotificationResult>> SendFCMBatchNotificationAsync(
            PushNotificationMessage message,
            List<string> deviceTokens,
            CancellationToken cancellationToken)
        {
            var results = new List<PushNotificationResult>();
            const int batchSize = 500; // FCM 批量发送限制

            for (int i = 0; i < deviceTokens.Count; i += batchSize)
            {
                var batch = deviceTokens.Skip(i).Take(batchSize).ToList();

                var payload = new
                {
                    message = new
                    {
                        tokens = batch,
                        notification = new
                        {
                            title = message.Title,
                            body = message.Body,
                            icon = message.Icon,
                            click_action = message.ClickUrl
                        },
                        data = message.Data ?? new Dictionary<string, object>()
                    }
                };

                var batchResult = await SendFCMBatchInternalAsync(payload, batch, cancellationToken);
                results.AddRange(batchResult);
            }

            return results;
        }

        private async Task<List<PushNotificationResult>> SendFCMBatchInternalAsync(
            object payload,
            List<string> deviceTokens,
            CancellationToken cancellationToken)
        {
            var results = new List<PushNotificationResult>();

            try
            {
                var httpClient = _httpClientFactory.CreateClient("FCM");
                var json = JsonSerializer.Serialize(payload);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

                httpClient.DefaultRequestHeaders.Authorization =
                    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _options.FCM!.ServerKey);

                var response = await httpClient.PostAsync(
                    "https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send",
                    content,
                    cancellationToken);

                var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);

                if (response.IsSuccessStatusCode)
                {
                    var responseData = JsonSerializer.Deserialize<JsonElement>(responseContent);
                    if (responseData.TryGetProperty("multicast_id", out var multicastId))
                    {
                        // 处理批量结果
                        var successCount = responseData.TryGetProperty("success", out var successProp) ? successProp.GetInt32() : 0;
                        var failureCount = responseData.TryGetProperty("failure", out var failureProp) ? failureProp.GetInt32() : 0;

                        // 为每个设备创建结果
                        for (int i = 0; i < deviceTokens.Count; i++)
                        {
                            results.Add(new PushNotificationResult
                            {
                                Success = i < successCount,
                                DeviceToken = deviceTokens[i],
                                Platform = PushPlatform.FCM,
                                SentTime = _clock.Now,
                                MessageId = multicastId.ToString()
                            });
                        }
                    }
                }
                else
                {
                    // 批量失败，为所有设备创建失败结果
                    results.AddRange(deviceTokens.Select(token => new PushNotificationResult
                    {
                        Success = false,
                        DeviceToken = token,
                        Platform = PushPlatform.FCM,
                        SentTime = _clock.Now,
                        ErrorMessage = $"FCM批量请求失败: {response.StatusCode}"
                    }));
                }
            }
            catch (Exception ex)
            {
                results.AddRange(deviceTokens.Select(token => new PushNotificationResult
                {
                    Success = false,
                    DeviceToken = token,
                    Platform = PushPlatform.FCM,
                    SentTime = _clock.Now,
                    ErrorMessage = ex.Message
                }));
            }

            return results;
        }

        private bool ValidateFCMToken(string token)
        {
            // FCM Token 通常长度在 140-170 字符之间，包含字母、数字、冒号和下划线
            return !string.IsNullOrWhiteSpace(token) &&
                   token.Length >= 140 &&
                   token.Length <= 170 &&
                   token.All(c => char.IsLetterOrDigit(c) || c == ':' || c == '-' || c == '_');
        }

        #endregion

        #region APNS 实现

        private async Task<PushNotificationResult> SendAPNSNotificationAsync(
            PushNotificationMessage message,
            string deviceToken,
            CancellationToken cancellationToken)
        {
            if (_options.APNS == null ||
                string.IsNullOrEmpty(_options.APNS.PrivateKey) ||
                string.IsNullOrEmpty(_options.APNS.TeamId))
            {
                return new PushNotificationResult
                {
                    Success = false,
                    ErrorMessage = "APNS配置不完整",
                    ErrorCode = "CONFIG_MISSING"
                };
            }

            try
            {
                var httpClient = _httpClientFactory.CreateClient("APNS");
                var jwt = GenerateAPNSJWT();

                var payload = new
                {
                    aps = new
                    {
                        alert = new
                        {
                            title = message.Title,
                            body = message.Body
                        },
                        badge = message.Badge,
                        sound = message.Sound ?? "default",
                        category = message.Category,
                        mutable_content = message.MutableContent,
                        content_available = message.ContentAvailable
                    },
                    custom_data = message.Data ?? new Dictionary<string, object>()
                };

                var json = JsonSerializer.Serialize(payload);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

                httpClient.DefaultRequestHeaders.Authorization =
                    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", jwt);
                httpClient.DefaultRequestHeaders.Add("apns-topic", _options.APNS.BundleId);
                if (!string.IsNullOrEmpty(_options.APNS.PushType))
                {
                    httpClient.DefaultRequestHeaders.Add("apns-push-type", _options.APNS.PushType);
                }

                var url = $"https://api.push.apple.com/3/device/{deviceToken}";
                var response = await httpClient.PostAsync(url, content, cancellationToken);

                var result = new PushNotificationResult
                {
                    DeviceToken = deviceToken,
                    Platform = PushPlatform.APNS,
                    SentTime = _clock.Now
                };

                if (response.IsSuccessStatusCode)
                {
                    result.Success = true;
                    result.MessageId = response.Headers.GetValues("apns-id").FirstOrDefault();
                }
                else
                {
                    result.Success = false;
                    result.ErrorMessage = $"APNS请求失败: {response.StatusCode}";
                    result.ErrorCode = ((int)response.StatusCode).ToString();

                    var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
                    try
                    {
                        var errorData = JsonSerializer.Deserialize<JsonElement>(responseContent);
                        if (errorData.TryGetProperty("reason", out var reasonProperty))
                        {
                            result.ErrorMessage = reasonProperty.GetString();
                        }
                    }
                    catch
                    {
                        // 忽略JSON解析错误
                    }
                }

                return result;
            }
            catch (Exception ex)
            {
                return new PushNotificationResult
                {
                    Success = false,
                    DeviceToken = deviceToken,
                    Platform = PushPlatform.APNS,
                    SentTime = _clock.Now,
                    ErrorMessage = ex.Message,
                    ErrorCode = "EXCEPTION"
                };
            }
        }

        private string GenerateAPNSJWT()
        {
            var privateKey = _options.APNS!.PrivateKey;
            var teamId = _options.APNS.TeamId;
            var keyId = _options.APNS.KeyId;

            var rsa = RSA.Create();
            rsa.ImportFromPem(privateKey);

            var credentials = new SigningCredentials(
                new RsaSecurityKey(rsa),
                SecurityAlgorithms.RsaSha256);

            var header = new JwtHeader(credentials)
            {
                { "kid", keyId },
                { "alg", "ES256" }
            };

            var payload = new JwtPayload
            {
                { "iss", teamId },
                { "iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds() }
            };

            var token = new JwtSecurityToken(header, payload);
            return new JwtSecurityTokenHandler().WriteToken(token);
        }

        private bool ValidateAPNSToken(string token)
        {
            // APNS Device Token 是64字符的十六进制字符串
            return !string.IsNullOrWhiteSpace(token) &&
                   token.Length == 64 &&
                   token.All(c => char.IsLetterOrDigit(c));
        }

        #endregion

        #region HMS 实现

        private async Task<PushNotificationResult> SendHMSNotificationAsync(
            PushNotificationMessage message,
            string deviceToken,
            CancellationToken cancellationToken)
        {
            if (_options.HMS == null ||
                string.IsNullOrEmpty(_options.HMS.AppId) ||
                string.IsNullOrEmpty(_options.HMS.AppSecret))
            {
                return new PushNotificationResult
                {
                    Success = false,
                    ErrorMessage = "HMS配置不完整",
                    ErrorCode = "CONFIG_MISSING"
                };
            }

            try
            {
                var accessToken = await GetHMSAccessTokenAsync(cancellationToken);

                var httpClient = _httpClientFactory.CreateClient("HMS");
                var payload = new
                {
                    message = new
                    {
                        token = deviceToken,
                        android = new
                        {
                            notification = new
                            {
                                title = message.Title,
                                body = message.Body,
                                icon = message.Icon,
                                click_action = new
                                {
                                    type = 1,
                                    intent = message.ClickUrl
                                }
                            },
                            data = message.Data ?? new Dictionary<string, object>()
                        }
                    }
                };

                var json = JsonSerializer.Serialize(payload);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

                httpClient.DefaultRequestHeaders.Authorization =
                    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);

                var url = $"https://push-api.cloud.huawei.com/v1/{_options.HMS.AppId}/messages:send";
                var response = await httpClient.PostAsync(url, content, cancellationToken);

                var result = new PushNotificationResult
                {
                    DeviceToken = deviceToken,
                    Platform = PushPlatform.HMS,
                    SentTime = _clock.Now
                };

                var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);

                if (response.IsSuccessStatusCode)
                {
                    result.Success = true;
                    var responseData = JsonSerializer.Deserialize<JsonElement>(responseContent);
                    if (responseData.TryGetProperty("code", out var codeProperty) &&
                        codeProperty.GetInt32() == 80000000 &&
                        responseData.TryGetProperty("msg_id", out var msgIdProperty))
                    {
                        result.MessageId = msgIdProperty.GetString();
                    }
                }
                else
                {
                    result.Success = false;
                    result.ErrorMessage = $"HMS请求失败: {response.StatusCode}";
                    result.ErrorCode = ((int)response.StatusCode).ToString();

                    try
                    {
                        var errorData = JsonSerializer.Deserialize<JsonElement>(responseContent);
                        if (errorData.TryGetProperty("error", out var errorProperty))
                        {
                            result.ErrorMessage = errorProperty.GetString();
                        }
                    }
                    catch
                    {
                        // 忽略JSON解析错误
                    }
                }

                return result;
            }
            catch (Exception ex)
            {
                return new PushNotificationResult
                {
                    Success = false,
                    DeviceToken = deviceToken,
                    Platform = PushPlatform.HMS,
                    SentTime = _clock.Now,
                    ErrorMessage = ex.Message,
                    ErrorCode = "EXCEPTION"
                };
            }
        }

        private async Task<string> GetHMSAccessTokenAsync(CancellationToken cancellationToken)
        {
            var cacheKey = "hms_access_token";
            var cachedToken = await _cache.GetStringAsync(cacheKey, cancellationToken);

            if (!string.IsNullOrEmpty(cachedToken))
            {
                return cachedToken;
            }

            var httpClient = _httpClientFactory.CreateClient();

            var postData = new Dictionary<string, string>
            {
                ["grant_type"] = "client_credentials",
                ["client_id"] = _options.HMS!.AppId!,
                ["client_secret"] = _options.HMS.AppSecret!
            };

            var content = new FormUrlEncodedContent(postData);
            var response = await httpClient.PostAsync(
                "https://oauth-login.cloud.huawei.com/oauth2/v3/token",
                content,
                cancellationToken);

            var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
            var tokenData = JsonSerializer.Deserialize<JsonElement>(responseContent);

            if (tokenData.TryGetProperty("access_token", out var tokenProperty))
            {
                var accessToken = tokenProperty.GetString()!;

                // 缓存token 1小时
                await _cache.SetStringAsync(
                    cacheKey,
                    accessToken,
                    new DistributedCacheEntryOptions
                    {
                        AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
                    },
                    cancellationToken);

                return accessToken;
            }

            throw new InvalidOperationException("获取HMS Access Token失败");
        }

        private bool ValidateHMSToken(string token)
        {
            // HMS Token 通常长度在 100-200 字符之间
            return !string.IsNullOrWhiteSpace(token) &&
                   token.Length >= 100 &&
                   token.Length <= 200;
        }

        #endregion

        #region 辅助方法

        private async Task UpdateStatisticsAsync(PushPlatform platform, bool success, string? errorMessage)
        {
            try
            {
                var today = _clock.Now.Date;
                var cacheKey = $"push_daily_stats:{platform}:{today:yyyy-MM-dd}";

                var cachedStats = await _cache.GetStringAsync(cacheKey);
                PushNotificationDailyStats stats;

                if (!string.IsNullOrEmpty(cachedStats))
                {
                    stats = JsonSerializer.Deserialize<PushNotificationDailyStats>(cachedStats)!;
                }
                else
                {
                    stats = new PushNotificationDailyStats
                    {
                        Date = today,
                        Platform = platform,
                        SuccessCount = 0,
                        FailureCount = 0
                    };
                }

                if (success)
                {
                    stats.SuccessCount++;
                }
                else
                {
                    stats.FailureCount++;
                    if (!string.IsNullOrEmpty(errorMessage))
                    {
                        stats.ErrorBreakdown.TryGetValue(errorMessage, out var errorCount);
                        stats.ErrorBreakdown[errorMessage] = errorCount + 1;
                    }
                }

                await _cache.SetStringAsync(
                    cacheKey,
                    JsonSerializer.Serialize(stats),
                    new DistributedCacheEntryOptions
                    {
                        AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1)
                    });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新推送统计信息失败: Platform={Platform}", platform);
            }
        }

        private string MaskDeviceToken(string token)
        {
            if (string.IsNullOrEmpty(token) || token.Length <= 8)
            {
                return "***";
            }

            return token.Substring(0, 4) + "***" + token.Substring(token.Length - 4);
        }

        #endregion
    }

    #region 配置类

    /// <summary>
    /// 推送通知选项配置
    /// </summary>
    public class PushNotificationOptions
    {
        /// <summary>
        /// FCM 配置
        /// </summary>
        public FCMOptions? FCM { get; set; }

        /// <summary>
        /// APNS 配置
        /// </summary>
        public APNSOptions? APNS { get; set; }

        /// <summary>
        /// HMS 配置
        /// </summary>
        public HMSOptions? HMS { get; set; }
    }

    #endregion

    #region 统计类

    /// <summary>
    /// 推送通知每日统计
    /// </summary>
    public class PushNotificationDailyStats
    {
        public DateTime Date { get; set; }
        public PushPlatform Platform { get; set; }
        public long SuccessCount { get; set; }
        public long FailureCount { get; set; }
        public Dictionary<string, long> ErrorBreakdown { get; set; } = new();
    }

    #endregion
}